//定义回调函数列表
let callbacks = [];
//节流阀开关
let waitings = false;
//定义回调队列函数
function flushCallbacks() {
    //callbacks.forEach(cbFn =>cbFn())
    //循环遍历这个回调队列,并且执行
    for (let i = 0; i < callbacks.length; i++) {
        let callback = callbacks[i];
        //debugger;
        callback()
    }
    //清空队列
    //关闭节流阀开关
    waitings = false;
    callbacks = [];

}

//定义异步执行更新渲染函数
export function nextTick(cb) {
    //回调列表数组添加回调方法 (操作watcher的渲染方法 flushSchedularQueue/或者自己调用的逻辑)
    callbacks.push(cb);
    //节流开关
    if (!waitings) {
        //节流开关打开
        waitings = true;
        //异步调用回调队列函数(操作watcher的渲染方法 flushSchedularQueue)
        Promise.resolve().then(flushCallbacks)
    }
}



//判断是否为对象/且不为空对象
export const isObject = (val) => typeof val == 'object' && val != null;
//生命周期钩子函数
const LIFECYCLE_HOOKS = [
    'beforeCreate',
    'created',
    'beforeMount',
    'mounted'
];
//数组收集,生命周期钩子函数
const starts = [];
//合并生命周期的函数
function mergeHook(parentVal, childVal) {
    //console.log(parentVal,childVal);
    //判断这个子对象的值存在么,不存在直接返回父对象
    if (!childVal) {
        return parentVal
    }
    //父/子对象都存在
    if (parentVal) {
        //父合并子
        return parentVal.concat(childVal)
    } else {
        //第一次父一定不存在,直接以数组类型的childVal
        return [childVal]
    }

}
//订阅生命周期函数
LIFECYCLE_HOOKS.forEach(hooks => {
    //合并生命周期函数
    starts[hooks] = mergeHook
})
//合并组件策略
starts.components = function (parentVal, childVal) {
    //继承父类
    const res = Object.create(parentVal)
    //浅拷贝,父类给子类
    if (childVal) {
        for (let key in childVal) {
            res[key] = childVal[key]
        }
    }
    return res;
}
//合并options函数(参数1:this.options(当前vue实例的配置项),参数2:mixin(调用mixin传入的配置项))
export function mergeOptions(parent, child) {
    //定义一个options对象接收合并后对象
    const options = {}
    //console.log(parent);
    //console.log(child);
    //遍历父配置项
    for (let key in parent) {
        //调用合并方法
        mergeField(key)
    }
    //遍历子配置项
    for (let key in child) {
        //如果父配置有值,减少遍历次数
        if (!parent.hasOwnProperty(key)) {
            //调用合并方法
            mergeField(key)
        }
    }
    //定义合并函数
    function mergeField(key) {
        //合并策略
        //{a:1} {a:2} =>  {a:2}
        //{a:1} {b:2} =>  {a:1,b:2}
        //自定义的逻辑
        if (starts[key]) {
            return options[key] = starts[key](parent[key], child[key])
        }
        //如果父/子的值都为对象
        if (isObject(parent[key]) && isObject(child[key])) {
            //options对象===扩展合并这两个对象
            options[key] = { ...parent[key], ...child[key] }
        } else {
            //判断这个child的值存在,存在则返回child的值,不存在返回parent的值
            options[key] = child[key] ? child[key] : parent[key]
        }
    }
    //返回这个合并项
    return options
}
//判断是否为真实的标签
function makeUp(str) {
    const map = {};
    str.split(',').forEach(tagName => {
        map[tagName] = true
    })
    return (tag) => map[tag] || false
}
export const isReservedTag = makeUp('a,p,ul,li,span,div,button,input,b')


